home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 12
/
CU Amiga Magazine's Super CD-ROM 12 (1997)(EMAP Images)(GB)[!][issue 1997-07].iso
/
System
/
HappyENV
/
HappyENV-Handler.asm
< prev
next >
Wrap
Assembly Source File
|
1996-06-18
|
38KB
|
1,922 lines
*************************
* HappyENV-Handler *
* 12.6.96 *
* (C) Martin Gierich *
*************************
; See documentation about Copyright&Disclaimer
;DEBUG = 1
;VOLUME = 1
;VERBOSE = 1
AUTOCOPY = 1
INCDIR source:stripinc/
INCLUDE exec/exec_lib.i
INCLUDE dos/dos_lib.i
INCLUDE dos/dosextens.i
INCLUDE dos/filehandler.i
INCLUDE dos/notify.i
INCLUDE debug.i
CALL MACRO
jsr _LVO\1(a6)
ENDM
mn_Node = 0
lib_Version = 20
_LVOToUpper = -174
DOS_TRUE = -1
DOS_FALSE = 0
MEMF_CLEAR = $10000
MAXPATH = 120
MAXNAME = 32
* notify list node structure
RSRESET
myn_Link RS.L 1
myn_Request RS.L 1 notify-request
myn_Key RS.L 1 pointer to file
myn_Name RS.B MAXPATH
myn_SIZEOF RS.W 0
* lock structure for Lock() and open files
RSRESET
myl_Link RS.L 1
myl_Key RS.L 1
myl_Access RS.L 1
myl_Task RS.L 1
myl_Volume RS.L 1
myl_Pos RS.L 1 position in file (read/write)
myl_Data RS.L 1 start of file data (read)
myl_Start RS.L 1 start of block list (write)
myl_Block RS.L 1 current block (write)
myl_BlockPos RS.L 1 position in current block (write)
myl_Size RS.L 1 size of file
myl_Mode RS.B 1 0=simple lock, -1=write, 1=read
myl_Pad RS.B 1
myl_SIZEOF RS.W 0
* structure for file or dir
RSRESET
myf_Link RS.L 1 next file/dir
myf_Parent RS.L 1 parent dir
myf_First RS.L 0 dir: points to first entry
myf_Size RS.L 1 file: size of filedata
myf_Type RS.B 1 -3=file, 0=hidden, 1=root, 2=dir
myf_Locks RS.B 1 number of locks, -1=write lock
myf_DataOffs RS.B 1 offset to start of data
myf_Name RS.W 0 name (dynamic), then data
* private main structure
RSRESET
CharTable RS.B 256
DosBase RS.L 1
MyProcess RS.L 1
MyMsgPort RS.L 1
MyMemPool RS.L 1
MyDeviceNode RS.L 1
MyVolumeBPTR RS.L 1
NotifyList RS.L 1
CopyfromLock RS.L 1
CopyfromPort RS.L 1
MyPacket RS.B sp_SIZEOF
VolumeNode RS.B DevList_SIZEOF
VolumeName RS.B MAXNAME
NotifyPort RS.B MP_SIZE
PacketPort RS.B MP_SIZE
FileSize RS.L 1
TotalSize RS.L 1
NumLocks RS.L 1
Kickver RS.W 1
WriteProtected RS.B 1
NSignal RS.B 1
PSignal RS.B 1
Paddy1 RS.B 1
RootDir RS.B myf_Name+8
Paddy2 RS.B 3
TempPath RS.B MAXPATH
TempName RS.B MAXNAME
My_SIZEOF RS.W 0
MyPkt = MyPacket+sp_Pkt
*******************************************************
*******************************************************
;a4=DOSpacket
;a5=private struct
;a6=execbase
start: movem.l d2-d7/a2-a6,-(sp) do some basic inits
move.l 4.w,a6
move.l #My_SIZEOF,d0
move.l #MEMF_CLEAR!1,d1
CALL AllocMem
tst.l d0
beq exit1
move.l d0,a5
DBUG1 txstart,a5
lea dosname(pc),a1
moveq #33,d0
CALL OpenLibrary
move.l d0,DosBase(a5)
beq exit2
move.w lib_Version(a6),Kickver(a5)
sub.l a1,a1
CALL FindTask
move.l d0,MyProcess(a5)
cmp.w #36,Kickver(a5)
blo.s .OS13
move.l d0,a0
bset #0,pr_Flags+3(a0)
.OS13 add.l #pr_MsgPort,d0
move.l d0,MyMsgPort(a5)
move.b #1,RootDir+myf_Type(a5)
cmp.w #39,Kickver(a5)
blo.s .OS20
moveq #1,d0
move.l #5000,d1
move.l #2000,d2
CALL CreatePool
move.l d0,MyMemPool(a5)
.OS20 move.l MyMsgPort(a5),a2 process startup message
bsr GetPacket
move.l d0,a4
move.l dp_Arg3(a4),d0
lsl.l #2,d0
move.l d0,MyDeviceNode(a5)
move.l d0,a0
move.l MyMsgPort(a5),dn_Task(a0)
clr.l dn_SegList(a0)
move.l dn_Name(a0),a0
lea RootDir+myf_Name(a5),a1
moveq #6,d0
bsr CopyBSTR2Char
moveq #DOS_TRUE,d0
move.l d0,dp_Res1(a4)
bsr ReplyPacket
lea VolumeNode(a5),a2 set up volume node
move.l a2,d0
lsr.l #2,d0
move.l d0,MyVolumeBPTR(a5)
moveq #2,d0
move.l d0,dl_Type(a2)
move.l MyMsgPort(a5),dl_Task(a2)
move.l #"DOS"<<8,dl_DiskType(a2)
lea volname(pc),a0
lea VolumeName(a5),a1
moveq #MAXNAME-2,d0
bsr CopyChar2BSTR
move.l d0,dl_Name(a2)
IFD VOLUME
move.l DosBase(a5),a0
move.l dl_Root(a0),a0
move.l rn_Info(a0),a0
add.l a0,a0
add.l a0,a0
move.l di_DevInfo(a0),d0
move.l d0,VolumeNode(a5)
move.l MyVolumeBPTR(a5),di_DevInfo(a0)
ENDC
bsr InitConversion init upper case table
lea NotifyPort(a5),a2 create msgport for notify
move.b #NT_MSGPORT,LN_TYPE(a2)
moveq #-1,d0
CALL AllocSignal
tst.l d0
bmi exit3
move.b d0,NSignal(a5)
move.b d0,MP_SIGBIT(a2)
move.l MyProcess(a5),MP_SIGTASK(a2)
lea MP_MSGLIST(a2),a0
move.b #NT_MESSAGE,LH_TYPE(a0)
NEWLIST a0
lea PacketPort(a5),a2 create msgport for DOSpackets
move.b #NT_MSGPORT,LN_TYPE(a2)
moveq #-1,d0
CALL AllocSignal
tst.l d0
bmi exit3
move.b d0,PSignal(a5)
move.b d0,MP_SIGBIT(a2)
move.l MyProcess(a5),MP_SIGTASK(a2)
lea MP_MSGLIST(a2),a0
move.b #NT_MESSAGE,LH_TYPE(a0)
NEWLIST a0
IFD AUTOCOPY
CALL Forbid
move.l DosBase(a5),a0
move.l dl_Root(a0),a0
move.l rn_Info(a0),a0
add.l a0,a0
add.l a0,a0
lea di_DevInfo(a0),a2
.C move.l (a2),d0
beq .D
lsl.l #2,d0
move.l d0,a2
move.l dol_Name(a2),a0
add.l a0,a0
add.l a0,a0
lea sysdisk(pc),a1
moveq #0,d0
move.b (a0)+,d0
bra.s .F
.G move.b (a1)+,d1
cmp.b (a0)+,d1
bne.s .C
.F dbra d0,.G
tst.b (a1)
bne.s .C
CALL Permit
move.l dol_Task(a2),CopyfromPort(a5)
beq.s .A
move.l dol_Lock(a2),d3
beq.s .A
move.l d1,CopyfromLock(a5)
lea envarc(pc),a0
lea TempName(a5),a1
moveq #MAXNAME-2,d0
bsr CopyChar2BSTR
move.l d0,d2
move.l d3,d1
moveq #ACCESS_READ,d3
moveq #ACTION_LOCATE_OBJECT,d0
bsr DoPacket
move.l d0,CopyfromLock(a5)
DBUG2 txcopy,CopyfromPort(a5),CopyfromLock(a5)
bra.s .A
.D CALL Permit
.A ENDC
loop move.l MyMsgPort(a5),a2 enter main loop
bsr GetPacket
move.l d0,a4
bsr GetNotify
clr.l dp_Res1(a4)
clr.l dp_Res2(a4)
move.l dp_Type(a4),d0
DBUG4 txpack,d0,dp_Arg1(a4),dp_Arg2(a4),dp_Arg3(a4)
move.l d0,d1
swap d1
tst.w d1
bne.s .A
lea start(pc),a1
lea JumpTable(pc),a2
moveq #0,d2
.C move.w (a2)+,d1
bpl.s .E
.A DBUG1 txerr1,d0
move.w #ERROR_ACTION_NOT_KNOWN,dp_Res2+2(a4)
bra.s .D
.E move.w (a2)+,d2
cmp.w d0,d1
bne.s .C
add.l d2,a1
jsr (a1)
.D IFD DEBUG
moveq #DOS_TRUE,d0
cmp.l dp_Res1(a4),d0
beq.s .H
DBUG2 txres,dp_Res1(a4),dp_Res2(a4)
.H ENDC
bsr ReplyPacket
bra loop
AExit addq.l #4,sp exit routine
moveq #DOS_TRUE,d0
move.l d0,dp_Res1(a4)
bsr ReplyPacket
tst.l NumLocks(a5)
bne loop
move.l MyDeviceNode(a5),a0
clr.l dn_Task(a0)
bsr FlushPackets
IFD VOLUME
move.l DosBase(a5),a0
move.l dl_Root(a0),a0
move.l rn_Info(a0),a0
add.l a0,a0
add.l a0,a0
move.l VolumeNode(a5),d0
move.l d0,di_DevInfo(a0)
ENDC
move.l CopyfromLock(a5),d1
beq.s .A
moveq #ACTION_FREE_LOCK,d0
bsr DoPacket
.A moveq #0,d0
move.b PSignal(a5),d0
CALL FreeSignal
moveq #0,d0
move.b NSignal(a5),d0
CALL FreeSignal
exit3 move.l DosBase(a5),a1
CALL CloseLibrary
exit2 move.l MyDeviceNode(a5),a0
clr.l dn_Task(a0)
DBUG2 txend,FileSize(a5),TotalSize(a5)
move.l MyMemPool(a5),d0
beq.s .A
move.l d0,a0
CALL DeletePool
.A move.l a5,a1
move.l #My_SIZEOF,d0
CALL FreeMem
exit1 movem.l (sp)+,d2-d7/a2-a6
moveq #0,d0
rts
*******************************************************
JumpTable:
dc.w ACTION_NIL,NoAction-start
dc.w ACTION_SET_PROTECT,NoAction-start
dc.w ACTION_SET_COMMENT,NoAction-start
dc.w ACTION_SET_DATE,NoAction-start
dc.w ACTION_FLUSH,NoAction-start
dc.w ACTION_IS_FILESYSTEM,NoAction-start
dc.w ACTION_DIE,AExit-start
dc.w ACTION_CURRENT_VOLUME,ACurrentVolume-start
dc.w ACTION_RENAME_DISK,ARenameDisk-start
dc.w ACTION_WRITE_PROTECT,AWriteProtect-start
dc.w ACTION_FINDUPDATE,AOpenNewfile-start
dc.w ACTION_FINDINPUT,AOpenOldfile-start
dc.w ACTION_FINDOUTPUT,AOpenNewfile-start
dc.w ACTION_END,ACloseFile-start
dc.w ACTION_SEEK,ASeekPosition-start
dc.w ACTION_READ,AReadFile-start
dc.w ACTION_WRITE,AWriteFile-start
dc.w ACTION_DELETE_OBJECT,ADeleteObject-start
dc.w ACTION_RENAME_OBJECT,ARenameObject-start
dc.w ACTION_CREATE_DIR,ACreateDir-start
dc.w ACTION_LOCATE_OBJECT,ALocateObject-start
dc.w ACTION_PARENT,AParentDir-start
dc.w ACTION_COPY_DIR,ADuplicateLock-start
dc.w ACTION_FREE_LOCK,AFreeLock-start
dc.w ACTION_SAME_LOCK,ASameLock-start
dc.w ACTION_EXAMINE_OBJECT,AExamineObject-start
dc.w ACTION_EXAMINE_FH,AExamineFH-start
dc.w ACTION_EXAMINE_NEXT,AExamineNext-start
dc.w ACTION_DISK_INFO,ADiskInfo1-start
dc.w ACTION_INFO,ADiskInfo2-start
dc.w ACTION_ADD_NOTIFY,AAddNotify-start
dc.w ACTION_REMOVE_NOTIFY,ARemoveNotify-start
dc.w ACTION_SET_FILE_SIZE,ASetFileSize-start
; dc.w ACTION_FH_FROM_LOCK,AFHfromLock-start
; dc.w ACTION_CHANGE_MODE,AChangeMode-start
dc.w ACTION_COPY_DIR_FH,ADupLockFromFH-start
dc.w ACTION_PARENT_FH,AParentFromFH-start
dc.w -1
IFD VOLUME
volname dc.b "Environment",0
ENDC
IFND VOLUME
volname dc.b "Env",0
ENDC
version dc.b "$VER: HappyENV-Handler 0.7 (12.6.96)",10,0
dosname dc.b "dos.library",0
utilname dc.b "utility.library",0
sysdisk dc.b "SYS",0
envarc dc.b "SYS:Prefs/Env-Archive",0
even
*******************************************************
* Init to-upper-conversion table
InitConversion:
lea CharTable(a5),a2
move.w #255,d0
.A move.b d0,0(a2,d0.w)
dbra d0,.A
moveq #"A",d0
.C move.b d0,"a"-"A"(a2,d0.w)
addq.w #1,d0
cmp.b #"Z"+1,d0
bne.s .C
move.w #192,d0
.F move.b d0,224-192(a2,d0.w)
addq.w #1,d0
cmp.b #222+1,d0
bne.s .F
lea utilname(pc),a1 open utility.library
moveq #37,d0
CALL OpenLibrary
tst.l d0
beq.s .D
move.l d0,a6
move.w #255,d2
.E move.w d2,d0
CALL ToUpper
move.b d0,0(a2,d2.w)
dbra d2,.E
move.l a6,a1
move.l 4.w,a6
CALL CloseLibrary
.D rts
* Wait for a packet, then get it
* ENTRY: a2=msgport
* EXIT: d0=packet
GetPacket:
.A move.l a2,a0
CALL WaitPort
move.l a2,a0
CALL GetMsg
tst.l d0
beq.s .A
move.l d0,a0
move.l mn_Node+LN_NAME(a0),d0
beq.s .A
rts
* Reply packet in a4
ReplyPacket:
move.l a4,a2
move.l dp_Port(a4),a0 reply port
move.l MyMsgPort(a5),dp_Port(a2)
* ENTRY: a2=packet to send, a0=msgport to send to
SendPacket:
move.l dp_Link(a2),a1 message to send
move.l a2,mn_Node+LN_NAME(a1)
clr.l mn_Node+LN_SUCC(a1)
clr.l mn_Node+LN_PRED(a1)
move.b #NT_MESSAGE,mn_Node+LN_TYPE(a1)
CALL PutMsg
rts
FlushPackets:
.A move.l MyMsgPort(a5),a0
CALL GetMsg
tst.l d0
beq.s .C
move.l d0,a0
move.l mn_Node+LN_NAME(a0),d0
beq.s .A
move.l d0,a4
clr.l dp_Res1(a4)
move.w #ERROR_ACTION_NOT_KNOWN,dp_Res2+2(a4)
bsr ReplyPacket
bra.s .A
.C rts
* Send a packet to the handler in CopyfromPort and wait for a reply
* ENTRY: d0=dp_Type, d1=dp_Arg1, d2=dp_Arg2, d3=dp_Arg3
* EXIT: d0=dp_Res1, d1=dp_Res2, Z-flag
DoPacket:
move.l a2,-(sp)
lea MyPacket(a5),a1
lea sp_Pkt(a1),a2
move.l a1,dp_Link(a2)
lea PacketPort(a5),a1
move.l a1,dp_Port(a2)
move.l d0,dp_Type(a2)
move.l d1,dp_Arg1(a2)
move.l d2,dp_Arg2(a2)
move.l d3,dp_Arg3(a2)
move.l CopyfromPort(a5),a0
bsr SendPacket
lea PacketPort(a5),a2
bsr GetPacket
move.l d0,a0
DBUG4 txpkt,a0,dp_Type(a0),dp_Res1(a0),dp_Res2(a0)
; bsr wait_c
move.l dp_Res2(a0),d1
move.l dp_Res1(a0),d0
move.l (sp)+,a2
rts
*******************************************************
*******************************************************
NoAction:
moveq #DOS_TRUE,d0
move.l d0,dp_Res1(a4)
rts
ACurrentVolume:
move.l MyVolumeBPTR(a5),dp_Res1(a4)
rts
ARenameDisk:
move.w #ERROR_DISK_WRITE_PROTECTED,dp_Res2+2(a4)
tst.b WriteProtected(a5)
bne.s .fail
move.l dp_Arg1(a4),a0
lea TempName(a5),a1
moveq #MAXNAME-2,d0
bsr CopyBSTR2Char
lea TempName(a5),a0
lea VolumeName(a5),a1
moveq #MAXNAME-2,d0
bsr CopyChar2BSTR
moveq #DOS_TRUE,d0
move.l d0,dp_Res1(a4)
.fail rts
AWriteProtect:
move.l dp_Arg1(a4),d0
move.b d0,WriteProtected(a5)
moveq #DOS_TRUE,d0
move.l d0,dp_Res1(a4)
rts
AOpenOldfile:
move.l dp_Arg1(a4),a3
add.l a3,a3
add.l a3,a3
clr.l fh_Interactive(a3)
move.l dp_Arg3(a4),a0
move.l dp_Arg2(a4),d0
moveq #ACCESS_READ,d2
bsr LocateObject
move.l d0,fh_Arg1(a3)
beq.s .fail
move.l d0,a0
move.l myl_Key(a0),a1
move.w #ERROR_OBJECT_WRONG_TYPE,dp_Res2+2(a4)
tst.b myf_Type(a1) do not open dirs
bmi.s .A
move.l a0,a1
bsr FreeLock
bra.s .fail
.A clr.l myl_Pos(a0)
move.l myf_Size(a1),myl_Size(a0)
moveq #0,d0
move.b myf_DataOffs(a1),d0
add.l d0,a1
move.l a1,myl_Data(a0)
clr.l myl_Start(a0)
clr.l myl_Block(a0)
clr.l myl_BlockPos(a0)
move.b #1,myl_Mode(a0)
moveq #DOS_TRUE,d0
move.l d0,dp_Res1(a4)
; DBUG1 txopeno,fh_Arg1(a3)
.fail rts
AOpenNewfile:
move.w #ERROR_DISK_WRITE_PROTECTED,dp_Res2+2(a4)
tst.b WriteProtected(a5)
bne .fail
move.w #ERROR_OBJECT_EXISTS,dp_Res2+2(a4)
move.l dp_Arg1(a4),a3
add.l a3,a3
add.l a3,a3
clr.l fh_Interactive(a3)
move.l dp_Arg2(a4),d0 does file already exist ?
move.l dp_Arg3(a4),a0
bsr DelSearchObject
beq.s .A
move.l d0,a1
tst.b myf_Type(a1) do not overwrite dirs
bpl .fail
bsr DeleteObject
beq .fail
.A bsr SplitPath
move.w #ERROR_DIR_NOT_FOUND,dp_Res2+2(a4)
move.l dp_Arg2(a4),d0
bsr CreatePath
beq .fail
move.l a3,-(sp)
move.l d0,a3
lea TempName(a5),a2
moveq #0,d2
bsr CreateNewObject
move.l (sp)+,a3
beq.s .fail
move.l d0,a2
moveq #ACCESS_WRITE,d2
bsr CreateLock
move.l d0,fh_Arg1(a3)
beq.s .fail
move.l d0,a0
move.b #-1,myl_Mode(a0)
clr.l myl_Pos(a0)
clr.l myl_Data(a0)
clr.l myl_Start(a0)
clr.l myl_Block(a0)
clr.l myl_BlockPos(a0)
clr.l myl_Size(a0)
moveq #DOS_TRUE,d0
move.l d0,dp_Res1(a4)
; DBUG1 txopenn,fh_Arg1(a3)
.fail rts
ACloseFile:
move.l dp_Arg1(a4),a1
cmp.b #-1,myl_Mode(a1)
beq.s .D
bsr FreeLock
bra.s .ok
.D move.l myl_Size(a1),d2
move.l myl_Key(a1),a2
move.l myf_Parent(a2),a3
lea myf_Name(a2),a2
bsr CreateNewObject
beq.s .fail
move.l d0,d4
move.l d0,a3
add.l d1,a3
move.l dp_Arg1(a4),a2
move.l myl_Start(a2),d3
.F tst.l d3
beq.s .A
move.l d3,-(sp)
move.l d3,a0
move.l (a0)+,d3
move.l (a0)+,d2
move.l a3,a1
move.l d2,d0
CALL CopyMem
add.l d2,a3
move.l d2,d0
addq.l #8,d0
move.l (sp)+,a1
bsr FreeMem
bra.s .F
.A move.l a2,a1
move.l myl_Key(a2),a2
bsr FreeLock
move.l a2,a1
bsr DeleteObj
beq.s .fail
move.l d4,a0
bsr CheckNotify
.ok moveq #DOS_TRUE,d0
move.l d0,dp_Res1(a4)
.fail rts
AWriteFile:
move.w #ERROR_DISK_WRITE_PROTECTED,dp_Res2+2(a4)
tst.b WriteProtected(a5)
bne .fail
moveq #-1,d0
move.l d0,dp_Res1(a4)
move.l dp_Arg1(a4),a2 lock
move.l dp_Arg2(a4),a3 buffer
move.l dp_Arg3(a4),d3 length
move.w #ERROR_WRITE_PROTECTED,dp_Res2+2(a4)
cmp.b #-1,myl_Mode(a2)
bne .fail
.F move.l d3,d2
move.l myl_Block(a2),d0
beq .E
move.l d0,a1
move.l 4(a1),d0
sub.l myl_BlockPos(a2),d0
beq.s .C
bmi.s .C
cmp.l d2,d0
bhs.s .D
move.l d0,d2
.D addq.l #8,a1
add.l myl_BlockPos(a2),a1
move.l a3,a0
move.l d2,d0
CALL CopyMem
DBUG2 txwins,d2,myl_Pos(a2)
add.l d2,a3
add.l d2,myl_Pos(a2)
add.l d2,myl_BlockPos(a2)
sub.l d2,d3
beq.s .ok
bra.s .F
.C move.l (a1),d0
beq.s .E
move.l d0,myl_Block(a2)
clr.l myl_BlockPos(a2)
bra .F
.E move.w #ERROR_DISK_FULL,dp_Res2+2(a4)
move.l d3,d0
addq.l #8,d0
bsr AllocMem
beq .fail
move.l myl_Block(a2),a0
move.l d0,myl_Block(a2)
move.l a0,d1
bne.s .A
lea myl_Start(a2),a0
.A move.l d0,(a0)
move.l d3,d2
move.l d0,a1
clr.l (a1)+
move.l d2,(a1)+
move.l a3,a0
move.l d2,d0
CALL CopyMem
add.l d2,myl_Size(a2)
add.l d2,myl_Pos(a2)
move.l d2,myl_BlockPos(a2)
.ok move.l dp_Arg3(a4),dp_Res1(a4)
DBUG3 txwrite,dp_Arg3(a4),myl_Pos(a2),myl_Size(a2)
.fail rts
AReadFile:
moveq #-1,d0
move.l d0,dp_Res1(a4)
move.l dp_Arg1(a4),a2
move.w #ERROR_READ_PROTECTED,dp_Res2+2(a4)
cmp.b #1,myl_Mode(a2)
bne.s .fail
move.l myl_Size(a2),d0
move.l myl_Pos(a2),a0
sub.l a0,d0
move.l dp_Arg3(a4),d2
cmp.l d0,d2
bls.s .A
exg.l d0,d2
.A move.l myl_Data(a2),d0
add.l d0,a0
move.l dp_Arg2(a4),a1
move.l d2,d0
CALL CopyMem
add.l d2,myl_Pos(a2)
move.l d2,dp_Res1(a4)
DBUG3 txread,d2,dp_Arg3(a4),myl_Pos(a2)
.fail rts
ASeekPosition
move.l dp_Arg1(a4),a2
move.l dp_Arg2(a4),d1 position
move.l dp_Arg3(a4),d2 mode
clr.w dp_Res2+2(a4)
move.l myl_Pos(a2),d3
move.l myl_Size(a2),d4
moveq #OFFSET_BEGINNING,d0
cmp.l d0,d2
beq.s .E
moveq #OFFSET_END,d0
cmp.l d0,d2
bne.s .C
add.l d4,d1
bra.s .E
.C moveq #OFFSET_CURRENT,d0
cmp.l d0,d2
bne.s .fail
add.l d3,d1
.E move.l d1,myl_Pos(a2)
bmi.s .A
cmp.l d1,d4
bhs.s Seeek
move.l d4,myl_Pos(a2)
bra.s .fail
.A clr.l myl_Pos(a2)
.fail move.w #ERROR_SEEK_ERROR,dp_Res2+2(a4)
moveq #-1,d3
Seeek cmp.b #-1,myl_Mode(a2)
bne.s .A
move.l myl_Pos(a2),d2
move.l myl_Start(a2),d0
beq.s .A
bra.s .E
.D move.l (a0),d0
beq.s .C
.E move.l d0,a0
move.l 4(a0),d1
sub.l d1,d2
beq.s .F
bpl.s .D
.F add.l d1,d2
.C move.l a0,myl_Block(a2)
move.l d2,myl_BlockPos(a2)
.A move.l d3,dp_Res1(a4)
DBUG1 txseek,myl_Pos(a2)
rts
ADeleteObject:
move.w #ERROR_DISK_WRITE_PROTECTED,dp_Res2+2(a4)
tst.b WriteProtected(a5)
bne.s .fail
move.w #ERROR_OBJECT_NOT_FOUND,dp_Res2+2(a4)
move.l dp_Arg1(a4),d0
move.l dp_Arg2(a4),a0
bsr SearchObject
beq.s .fail
movem.l d0-d1,-(sp)
move.l d0,a0
moveq #1,d0
bsr NotifyObject
movem.l (sp)+,d0-d1
move.l d0,a1
bsr DeleteObject
beq.s .fail
moveq #DOS_TRUE,d0
move.l d0,dp_Res1(a4)
.fail rts
ARenameObject:
move.w #ERROR_DISK_WRITE_PROTECTED,dp_Res2+2(a4)
tst.b WriteProtected(a5)
bne .fail
move.w #ERROR_OBJECT_NOT_FOUND,dp_Res2+2(a4)
move.l dp_Arg1(a4),d0
move.l dp_Arg2(a4),a0
bsr SearchObject
beq .fail
move.l d0,a3
move.l d1,d3
move.w #ERROR_OBJECT_IN_USE,dp_Res2+2(a4)
tst.b myf_Locks(a3)
bne .fail
move.l a3,a0
bsr NotifyObject
move.w #ERROR_OBJECT_EXISTS,dp_Res2+2(a4)
move.l dp_Arg3(a4),d0
move.l dp_Arg4(a4),a0
bsr DelSearchObject
bne .fail
bsr SplitPath
move.w #ERROR_DIR_NOT_FOUND,dp_Res2+2(a4)
move.l dp_Arg3(a4),d0
bsr SearchPath
beq .fail
move.l a3,-(sp)
moveq #0,d2
tst.b myf_Type(a3)
bpl.s .D
move.l myf_Size(a3),d2
.D move.l d0,a3
lea TempName(a5),a2
bsr CreateNewObject
move.l (sp)+,a3
beq.s .fail
move.l d0,a2
move.b myf_Type(a3),myf_Type(a2)
bpl.s .A
move.l a2,a1 rename file
add.l d1,a1
move.l a3,a0
moveq #0,d0
move.b myf_DataOffs(a3),d0
add.l d0,a0
move.l myf_Size(a3),d0
CALL CopyMem
bra.s .C
.A move.l myf_First(a3),d0 rename dir
clr.l myf_First(a3)
move.l d0,myf_First(a2)
beq.s .C
.E move.l d0,a0
move.l a2,myf_Parent(a0)
move.l myf_Link(a0),d0
bne.s .E
.C move.l d3,d1 end rename
move.l a3,a1
bsr DeleteObject
beq.s .fail
move.l a2,a0
bsr CheckNotify
moveq #DOS_TRUE,d0
move.l d0,dp_Res1(a4)
.fail rts
*******************************************************
ALocateObject:
move.l dp_Arg1(a4),d0
move.l dp_Arg2(a4),a0
move.l dp_Arg3(a4),d2
bsr LocateObject
lsr.l #2,d0
move.l d0,dp_Res1(a4)
rts
ADupLockFromFH:
move.l dp_Arg1(a4),d0
bra.s DupLock
ADuplicateLock:
move.l dp_Arg1(a4),d0
lsl.l #2,d0
DupLock beq.s .fail
move.l d0,a0
move.l myl_Key(a0),a2
moveq #ACCESS_READ,d2
bsr CreateLock
lsr.l #2,d0
move.l d0,dp_Res1(a4)
.fail rts
AParentFromFH:
move.l dp_Arg1(a4),d0
bra.s ParentD
AParentDir:
move.l dp_Arg1(a4),d0
lsl.l #2,d0
ParentD beq.s .fail
move.l d0,a0
move.l myl_Key(a0),a2
move.l myf_Parent(a2),d0
beq.s .fail
move.l d0,a2
moveq #ACCESS_READ,d2
bsr CreateLock
lsr.l #2,d0
move.l d0,dp_Res1(a4)
.fail rts
AFreeLock:
move.l dp_Arg1(a4),d0
beq.s .fail
lsl.l #2,d0
move.l d0,a1
bsr FreeLock
moveq #DOS_TRUE,d0
move.l d0,dp_Res1(a4)
.fail rts
ASameLock:
moveq #LOCK_SAME_VOLUME,d0
move.l d0,dp_Res1(a4)
move.l dp_Arg1(a4),a0
add.l a0,a0
add.l a0,a0
move.l dp_Arg2(a4),a1
add.l a1,a1
add.l a1,a1
move.l myl_Key(a0),d0
cmp.l myl_Key(a1),d0
bne.s .A
moveq #LOCK_SAME,d0
move.l d0,dp_Res1(a4)
.A rts
AExamineFH:
move.l dp_Arg1(a4),a0
bra.s Exami
AExamineObject:
move.l dp_Arg1(a4),a0
add.l a0,a0
add.l a0,a0
Exami move.l myl_Key(a0),a0
move.l dp_Arg2(a4),a1
add.l a1,a1
add.l a1,a1
; DBUG1 txexam,a0
move.l a1,a2
moveq #fib_SIZEOF/4-1,d0
.D clr.l (a2)+
dbra d0,.D
* ENTRY: a0=file, a1=fib
ExamineObject:
moveq #0,d1
move.b myf_Type(a0),d0
ext.w d0
ext.l d0
move.l d0,fib_DirEntryType(a1)
move.l d0,fib_EntryType(a1)
bpl.s .A
move.l myf_Size(a0),d1
.A move.l a0,fib_DiskKey(a1)
move.l d1,fib_Size(a1)
move.l d1,fib_NumBlocks(a1)
lea myf_Name(a0),a0
lea fib_FileName(a1),a1
moveq #106,d0
bsr CopyChar2BSTR
moveq #DOS_TRUE,d0
move.l d0,dp_Res1(a4)
rts
AExamineNext:
move.l dp_Arg1(a4),a2
add.l a2,a2
add.l a2,a2
move.l dp_Arg2(a4),a1
add.l a1,a1
add.l a1,a1
move.l fib_DiskKey(a1),a0
; DBUG1 txexnx,a0
cmp.l myl_Key(a2),a0
bne.s .A
move.w #ERROR_OBJECT_WRONG_TYPE,dp_Res2+2(a4)
tst.b myf_Type(a0)
bmi.s .fail
move.l myf_First-myf_Link(a0),a0
bra.s .C
.A move.l myf_Link(a0),a0
.C move.w #ERROR_NO_MORE_ENTRIES,dp_Res2+2(a4)
move.l a0,d0
beq.s .fail
tst.b myf_Type(a0)
beq.s .A
bra ExamineObject
.fail rts
ADiskInfo1:
move.l dp_Arg1(a4),a0
bra.s DiskInfo
ADiskInfo2:
move.l dp_Arg2(a4),a0
DiskInfo:
add.l a0,a0
add.l a0,a0
move.l a0,a1
moveq #id_SIZEOF/4-1,d0
.D clr.l (a1)+
dbra d0,.D
move.l NumLocks(a5),id_NumSoftErrors(a0)
moveq #ID_VALIDATED,d0
tst.b WriteProtected(a5)
beq.s .C
moveq #ID_WRITE_PROTECTED,d0
.C move.l d0,id_DiskState(a0)
move.l #1024,d1
move.l d1,id_BytesPerBlock(a0)
lsr.l #1,d1
move.l FileSize(a5),d0
add.l d1,d0
lsr.l #8,d0
lsr.l #2,d0
move.l d0,id_NumBlocksUsed(a0)
move.l TotalSize(a5),d0
add.l d1,d0
lsr.l #8,d0
lsr.l #2,d0
bne.s .A
moveq #1,d0
.A move.l d0,id_NumBlocks(a0)
move.l #"DOS"<<8,id_DiskType(a0)
move.l MyVolumeBPTR(a5),id_VolumeNode(a0)
moveq #DOS_TRUE,d0
move.l d0,dp_Res1(a4)
rts
ACreateDir:
move.w #ERROR_DISK_WRITE_PROTECTED,dp_Res2+2(a4)
tst.b WriteProtected(a5)
bne.s .fail
move.w #ERROR_OBJECT_EXISTS,dp_Res2+2(a4)
move.l dp_Arg1(a4),d0
move.l dp_Arg2(a4),a0
bsr DelSearchObject
bne.s .fail
bsr SplitPath
move.w #ERROR_DIR_NOT_FOUND,dp_Res2+2(a4)
move.l dp_Arg1(a4),d0
bsr CreatePath
beq.s .fail
move.l d0,a3
lea TempName(a5),a2
moveq #0,d2
bsr CreateNewObject
beq.s .fail
move.l d0,a2
move.b #2,myf_Type(a2)
moveq #ACCESS_WRITE,d2
bsr CreateLock
beq.s .fail
move.l d0,a0
lsr.l #2,d0
move.l d0,dp_Res1(a4)
move.l myl_Key(a0),a0
bsr CheckNotify
.fail rts
*******************************************************
ASetFileSize:
move.l dp_Arg1(a4),a2
move.l myl_Size(a2),dp_Res1(a4)
rts
AFHfromLock:
AChangeMode:
rts
*******************************************************
AAddNotify:
move.w #ERROR_NO_FREE_STORE,dp_Res2+2(a4)
move.l dp_Arg1(a4),a3
move.l #myn_SIZEOF,d0
bsr AllocMem
beq.s .fail
move.l d0,a2
lea NotifyList(a5),a0
move.l (a0),myn_Link(a2)
move.l a2,(a0)
move.l a3,myn_Request(a2)
move.l nr_FullName(a3),a0
lea myn_Name(a2),a1
moveq #MAXPATH-1,d0
bsr CopyChar2Char
lea myn_Name(a2),a0
lea TempPath(a5),a1
moveq #MAXPATH-1,d0
bsr CopyChar2Char
moveq #0,d0
bsr SearchPath
move.l d0,myn_Key(a2)
IFD DEBUG
lea myn_Name(a2),a0
DBUG4 txanoti,a2,a3,a0,d0
ENDC
move.l nr_Flags(a3),d0
btst #NRB_NOTIFY_INITIAL,d0
beq.s .A
bsr SendNotify
.A moveq #DOS_TRUE,d0
move.l d0,dp_Res1(a4)
.fail rts
ARemoveNotify:
move.w #ERROR_OBJECT_IN_USE,dp_Res2+2(a4)
move.l dp_Arg1(a4),a2
tst.l nr_MsgCount(a2)
bne.s .fail
move.w #ERROR_OBJECT_NOT_FOUND,dp_Res2+2(a4)
lea NotifyList(a5),a1
.A move.l (a1),d0
beq.s .fail
move.l a1,a0
move.l d0,a1
cmp.l myn_Request(a1),a2
bne.s .A
move.l myn_Link(a1),myn_Link(a0)
DBUG2 txrnoti,a1,a2
move.l #myn_SIZEOF,d0
bsr FreeMem
moveq #DOS_TRUE,d0
move.l d0,dp_Res1(a4)
.fail rts
* Update myn_Key of notification list and do notify
* ENTRY: a0=file
UpdateNotify:
move.l a2,-(sp)
lea NotifyList(a5),a2
bra.s .A
.C move.l d0,a2
tst.l myn_Key(a2)
bne.s .A
lea myn_Name(a2),a0
lea TempPath(a5),a1
moveq #MAXPATH-1,d0
bsr CopyChar2Char
moveq #0,d0
bsr SearchPath
move.l d0,myn_Key(a2)
IFD DEBUG
beq.s .A
lea myn_Name(a2),a0
DBUG2 txunoti,a0,d0
ENDC
.A move.l (a2),d0
bne.s .C
move.l (sp)+,a2
rts
* Check notification list for file/dir and parent dir and notify it.
* ENTRY: a0=file
CheckNotify:
move.l a0,-(sp)
IFD DEBUG
lea myf_Name(a0),a0
DBUG1 txcnoti,a0
ENDC
bsr UpdateNotify
move.l (sp)+,a0
NotifyObject:
bsr NotifyObj
move.l myf_Parent(a0),d1
move.l d1,a0
beq.s .E
bsr NotifyObj
.E rts
NotifyObj:
lea NotifyList(a5),a2
bra.s .A
.C move.l d0,a2
cmp.l myn_Key(a2),a0
bne.s .A
move.l a0,-(sp)
move.l myn_Request(a2),a3
bsr SendNotify
move.l (sp)+,a0
.A move.l (a2),d0
bne.s .C
rts
* Send a Notify message or set a Notify signal
* ENTRY: a3=NotifyRequest
SendNotify:
btst #NRB_SEND_SIGNAL,nr_Flags+3(a3)
beq.s .C
move.l nr_Task(a3),a1
IFD DEBUG
move.l LN_NAME(a1),d0
lea myn_Name(a2),a0
DBUG2 txsnoti,d0,a0
ENDC
moveq #0,d0
move.b nr_SignalNum(a3),d1
bset d1,d0
CALL Signal
rts
.C btst #NRB_SEND_MESSAGE,nr_Flags+3(a3)
beq .D
moveq #NotifyMessage_SIZEOF,d0
bsr AllocMem
beq .D
move.l d0,a0
move.l d0,a1
moveq #NotifyMessage_SIZEOF/2-1,d0
.A clr.w (a0)+
dbra d0,.A
move.b #NT_MESSAGE,LN_TYPE(a1)
lea NotifyPort(a5),a0
move.l a0,MN_REPLYPORT(a1)
move.w #NotifyMessage_SIZEOF,MN_LENGTH(a1)
move.l #$40000000,nm_Class(a1)
move.w #$1234,nm_Code(a1)
move.l a3,nm_NReq(a1)
IFD DEBUG
move.l a2,-(sp)
move.l nr_Port(a3),a0
move.l MP_SIGTASK(a0),a0
move.l LN_NAME(a0),a0
lea myn_Name(a2),a2
DBUG3 txmnoti,a1,a0,a2
move.l (sp)+,a2
ENDC
move.l nr_Port(a3),a0
CALL PutMsg
addq.l #1,nr_MsgCount(a3)
; btst #NRB_WAIT_REPLY,nr_Flags+3(a3)
; beq.s .D
; lea NotifyPort(a5),a0
; CALL WaitPort
; bsr GetNotify
.D rts
* Handle replies of Notify message
GetNotify:
.A lea NotifyPort(a5),a0
CALL GetMsg
tst.l d0
beq.s .E
move.l d0,a1
DBUG1 txgnoti,a1
move.l nm_NReq(a1),a0
subq.l #1,nr_MsgCount(a0)
moveq #NotifyMessage_SIZEOF,d0
bsr FreeMem
bra.s .A
.E rts
*******************************************************
*******************************************************
* ENTRY: a2=name, a3=parent dir, d2=data size
* EXIT: d1=offset of data, d0=new file, Z-flag
CreateNewObject:
move.w #ERROR_DISK_FULL,dp_Res2+2(a4)
CreateNewObj:
movem.l d3/a2-a3,-(sp)
move.l a2,a0
moveq #myf_Name,d3
.D addq.l #1,d3
tst.b (a0)+
bne.s .D
addq.l #1,d3
bclr #0,d3
move.l d3,d0
add.l d2,d0
bsr AllocMem
beq.s .fail
move.l d0,a1
lea myf_First(a3),a0
.C move.l (a0),d0
beq.s .A
move.l d0,a0
bra.s .C
.A move.l a1,(a0)
clr.l myf_Link(a1)
move.l a3,myf_Parent(a1)
move.l d2,myf_Size(a1)
add.l d2,FileSize(a5)
move.b #-3,myf_Type(a1)
move.b d3,myf_DataOffs(a1)
clr.b myf_Locks(a1)
lea myf_Name(a1),a0
.E move.b (a2)+,(a0)+
bne.s .E
move.l d3,d1
move.l a1,d0
.fail IFD DEBUG
move.l d0,-(sp)
lea myf_Name(a1),a2
move.l myf_Size(a1),d0
DBUG3 txcreat,a2,a1,d0
move.l (sp)+,d0
ENDC
movem.l (sp)+,d3/a2-a3
rts
* Delete file in a1
* ENTRY: a1=file
* EXIT: d0=success, Z-flag
DeleteObj:
move.w #ERROR_OBJECT_NOT_FOUND,dp_Res2+2(a4)
move.l myf_Parent(a1),a0
move.l myf_First(a0),d0
sub.l a0,a0
.C move.l a0,d1
move.l d0,a0
tst.l d0
beq DelErr
move.l myf_Link(a0),d0
cmp.l a1,a0
bne.s .C
* ENTRY: a1=file d1=pred.
DeleteObject:
move.l d2,-(sp)
moveq #0,d0
move.w #ERROR_OBJECT_IN_USE,dp_Res2+2(a4)
tst.b myf_Locks(a1)
bne.s .fail
tst.b myf_Type(a1)
bmi.s .C
move.w #ERROR_DIRECTORY_NOT_EMPTY,dp_Res2+2(a4)
tst.l myf_First(a1) check if dir is empty
bne.s .fail
.C move.l myf_Link(a1),d2 rearrange links
move.l d1,a0
tst.l d1
bne.s .A
move.w #ERROR_OBJECT_WRONG_TYPE,dp_Res2+2(a4)
move.l myf_Parent(a1),d1
beq.s .fail do not delete root
move.l d1,a0
lea myf_First-myf_Link(a0),a0
.A move.l d2,myf_Link(a0)
DBUG1 txdel,a1
lea NotifyList(a5),a0
bra.s .D
.E move.l d0,a0
cmp.l myn_Key(a0),a1
bne.s .D
clr.l myn_Key(a0) check notifications
.D move.l (a0),d0
bne.s .E
moveq #0,d0 free memory
move.b myf_DataOffs(a1),d0
move.l myf_Size(a1),d1
add.l d1,d0
sub.l d1,FileSize(a5)
bsr FreeMem
moveq #1,d0
.fail move.l (sp)+,d2
DelErr tst.l d0
rts
* ENTRY: d0=BPTR parent lock, a0=name (BSTR), d2=access mode
* EXIT: d0=APTR lock, Z-flag
* Must preserve a3
LocateObject:
move.w #ERROR_OBJECT_NOT_FOUND,dp_Res2+2(a4)
move.l d0,d3
bsr SearchObject
bne.s .A
moveq #ACCESS_READ,d0
cmp.l d0,d2
bne.s .C
tst.b WriteProtected(a5)
bne.s .C
tst.l CopyfromLock(a5)
beq.s .C
move.l d3,d0
bsr CalcFullName
bne.s .A
.C moveq #0,d0
bra LOfail2
.A move.l d0,a2
tst.b myf_Type(a2) hidden ?
beq.s .C
* Create lock on file/dir
* ENTRY: a2=file, d2=access mode
* EXIT: d0=success, Z-flag
CreateLock:
moveq #0,d0
move.w #ERROR_OBJECT_IN_USE,dp_Res2+2(a4)
lea myf_Locks(a2),a0
moveq #ACCESS_WRITE,d1
cmp.l d1,d2
bne.s .A
tst.b (a0)
bne.s LOfail
move.b d1,(a0)
bra.s .C
.A tst.b (a0)
bmi.s LOfail
addq.b #1,(a0)
.C move.w #ERROR_NO_FREE_STORE,dp_Res2+2(a4)
move.l #myl_SIZEOF,d0
bsr AllocMem
beq.s LOfail
move.l d0,a0
clr.l myl_Link(a0)
move.l a2,myl_Key(a0)
move.l d2,myl_Access(a0)
move.l MyMsgPort(a5),myl_Task(a0)
move.l MyVolumeBPTR(a5),myl_Volume(a0)
clr.b myl_Mode(a0)
addq.l #1,NumLocks(a5)
LOfail IFD DEBUG
move.l d0,d1
lsr.l #2,d1
lea myf_Name(a2),a0
DBUG3 txlock,a0,d1,d2
ENDC
LOfail2 tst.l d0
rts
* Free lock in a1 (APTR)
FreeLock:
; move.w #ERROR_UNLOCK_ERROR,dp_Res2+2(a4)
IFD DEBUG
move.l a1,d0
lsr.l #2,d0
DBUG1 txulock,d0
ENDC
move.l myl_Key(a1),a0
tst.b myf_Locks(a0)
beq.s .A
bmi.s .D
subq.b #1,myf_Locks(a0)
bra.s .A
.D clr.b myf_Locks(a0)
.A move.l #myl_SIZEOF,d0
bsr FreeMem
subq.l #1,NumLocks(a5)
rts
*******************************************************
* ENTRY: d0=size
AllocMem:
add.l d0,TotalSize(a5)
move.l MyMemPool(a5),d1
beq.s .A
move.l d1,a0
CALL AllocPooled
bra.s .C
.A moveq #1,d1
CALL AllocMem
.C tst.l d0
rts
* ENTRY: d0=size, a1=address
FreeMem:
sub.l d0,TotalSize(a5)
move.l MyMemPool(a5),d1
beq.s .A
move.l d1,a0
CALL FreePooled
rts
.A CALL FreeMem
rts
* Copy BSTR in a0 to string in a1, d0=maxlength without 0
CopyBSTR2Char:
add.l a0,a0
add.l a0,a0
moveq #0,d1
move.b (a0)+,d1
cmp.l d0,d1
bls.s .C
exg.l d0,d1
bra.s .C
.A move.b (a0)+,(a1)+
.C dbra d1,.A
clr.b (a1)
rts
* Copy string in a0 to BSTR in a1, d0=maxlength without 0
* EXIT: d0=BPTR
CopyChar2BSTR:
moveq #-1,d1
addq.l #1,a1
.A addq.l #1,d1
cmp.l d0,d1
bhs.s .C
move.b (a0)+,(a1)+
bne.s .A
subq.l #1,a1
.C clr.b (a1)
sub.l d1,a1
subq.l #1,a1
move.b d1,(a1)
move.l a1,d0
lsr.l #2,d0
rts
CopyChar2Char:
* Copy string in a0 to string in a1, d0=maxlength without 0
.C move.b (a0)+,(a1)+
beq.s .A
subq.l #1,d0
bne.s .C
.A rts
* Same as SearchPath, but creates it if not existent
* ENTRY: TempPath=dirname, d0=lock on dir
* EXIT: d0=ptr to file, Z-flag, d1=previous file
CreatePath:
moveq #1,d1
bra.s SearchP
* Same as SearchObject, but deletes hidden files
DelSearchObject
bsr SearchObject
beq.s .A
move.l d0,a1
tst.b myf_Type(a1)
bne .A
bsr DeleteObject delete hidden file
moveq #0,d0
.A rts
* Look for object with path
* ENTRY: a0=filename (BSTR), d0=lock on dir
* EXIT: d0=ptr to file, Z-flag, d1=previous file, TempPath=name
SearchObject:
move.l d0,-(sp)
lea TempPath(a5),a1
moveq #MAXPATH-1,d0
bsr CopyBSTR2Char
move.l (sp)+,d0
* Same as SearchObject, but name already copied to TempPath
SearchPath: ;TempPath=dirname, d0=lock on dir
moveq #0,d1
SearchP movem.l d2-d7/a2-a4,-(sp)
move.l d1,d7
lea RootDir(a5),a1
lea TempPath(a5),a0
.A cmp.b #":",(a0)+ skip volume name
beq.s .E
tst.b -1(a0)
bne.s .A
lea TempPath(a5),a0
.D lsl.l #2,d0 use root or locked dir
beq.s .E
move.l d0,a2
move.l myl_Key(a2),a1 dir represented by lock
.E
* ENTRY: a0=Name, a1=parent dir; mind SP !
SearchName:
.A moveq #0,d0
.D cmp.b #"/",(a0) parent dir when starting with /
bne.s .H
move.l myf_Parent(a1),d2
beq.s .fail
move.l d2,a1
addq.l #1,a0
bra.s .D
.H tst.b (a0) check for empty string
beq.s .G
move.l a0,a4
moveq #0,d3
.C addq.l #1,d3 look for / or end
tst.b (a4)
beq.s .E
cmp.b #":",(a4)
beq.s .fail
cmp.b #"/",(a4)+
bne.s .C
.E tst.b myf_Type(a1)
bmi.s .fail
move.l a1,d2
bsr SearchEntry search in dir
bne.s .F
tst.l d7 check for CreatePath
beq.s .G
movem.l d1-d3/a0/a2-a3,-(sp)
move.l d2,a3
move.l a0,a2
move.b -(a4),d3
tst.b 1(a4)
beq.s .I
clr.b (a4)
.I moveq #0,d2
bsr CreateNewObj create new dir
move.b d3,(a4)+
move.l d0,a1
movem.l (sp)+,d1-d3/a0/a2-a3
tst.l d0
beq.s .G
move.b #2,myf_Type(a1)
.F move.l a4,a0
bra.s .A continue looking for / or end
.G move.l a1,d0
.fail IFD DEBUG
lea TempPath(a5),a0
DBUG2 txfnd,a0,d0
ENDC
movem.l (sp)+,d2-d7/a2-a4
tst.l d0
rts
* ENTRY: a2=name, a3=parent dir, d2=data size
* EXIT: d1=offset of data, d0=new file, Z-flag
* Look for object in dir
* ENTRY: a0=file/dir name, a1=ptr to dir, d3=length of name
* EXIT: a1=ptr to file or 0, Z-flag
SearchEntry:
moveq #0,d5
moveq #0,d6
move.l myf_First(a1),d0
sub.l a1,a1
.C move.l a1,d1
move.l d0,a1
tst.l d0
beq.s .fail
move.l myf_Link(a1),d0
lea myf_Name(a1),a2
move.l a0,a3
move.l d3,d4
bra.s .E
.A move.b (a2)+,d5
move.b CharTable(a5,d5.l),d5
move.b (a3)+,d6
move.b CharTable(a5,d6.l),d6
cmp.b d5,d6
bne.s .C
.E subq.l #1,d4
bne.s .A
tst.b (a2)
bne.s .C
; IFD DEBUG
; lea myf_Name(a1),a3
; DBUG1 txentry,a3
; ENDC
.fail move.l a1,d0
rts
*Splits path with file into path=TempPath and file=TempName
SplitPath
move.l a2,-(sp)
lea TempPath(a5),a0
move.l a0,a1
.A tst.b (a0)+
bne.s .A
.D cmp.b #"/",-(a0)
beq.s .C
cmp.b #":",(a0)
beq.s .C
cmp.l a0,a1
bne.s .D
move.l a0,a1
bra.s .G
.C move.l a0,a1
addq.l #1,a1
.G lea TempName(a5),a2
.E move.b (a1)+,(a2)+
bne.s .E
cmp.b #":",(a0)
bne.s .F
addq.l #1,a0
.F clr.b (a0)
move.l (sp)+,a2
IFD DEBUG
lea TempPath(a5),a0
lea TempName(a5),a1
DBUG2 txsplit,a0,a1
ENDC
rts
* ENTRY: a1=object
* EXIT: a0=full name (root name not included) in TempPath
* Only used by CalcFullName
GetFullName:
move.l d2,-(sp)
lea TempPath+MAXPATH+MAXNAME-1(a5),a0
clr.b (a0)
move.w #MAXPATH+MAXNAME-1,d2
.A move.l myf_Parent(a1),d0
beq.s .ok
lea myf_Name(a1),a1
moveq #-1,d1
.C addq.l #1,d1
tst.b (a1)+
bne.s .C
subq.l #1,a1
sub.w d1,d2
bmi.s .ok
tst.b (a0)
beq.s .D
move.b #"/",-(a0)
subq.w #1,d2
bra.s .D
.E move.b -(a1),-(a0)
.D dbra d1,.E
move.l d0,a1
bra.s .A
.ok move.l (sp)+,d2
rts
* ENTRY: TempPath=name, d0=BPTR parent lock
* Only used by LocateObject
CalcFullName:
movem.l d2-d5/a2-a4,-(sp)
moveq #0,d4 d4=return code
bsr CreatePath
beq .fail
move.l d0,a1
move.l d0,a2
clr.b myf_Type(a1) a2=new hidden file
bsr GetFullName
DBUG1 txfull,a0
lea TempPath(a5),a1
moveq #MAXPATH-2,d0
bsr CopyChar2BSTR
move.l d0,d5 d5=BSTR full name
move.l #fib_SIZEOF+fh_SIZEOF,d0
bsr AllocMem
beq .fail
move.l d0,a3 a3=File info block
lea fib_SIZEOF(a3),a4 a4=file handle
move.l CopyfromLock(a5),d1
move.l d5,d2
moveq #ACCESS_READ,d3
moveq #ACTION_LOCATE_OBJECT,d0
bsr DoPacket
beq .fail2
move.l d0,d3 d3=lock on file
move.l d3,d1
move.l a3,d2
lsr.l #2,d2
moveq #ACTION_EXAMINE_OBJECT,d0
bsr DoPacket
move.l d0,-(sp)
move.l d3,d1
moveq #ACTION_FREE_LOCK,d0
bsr DoPacket
move.l (sp)+,d0
beq.s .fail2
tst.l fib_DirEntryType(a3)
bpl.s .fail2
move.l a4,d1
lsr.l #2,d1
move.l CopyfromLock(a5),d2
move.l d5,d3
move.l #ACTION_FINDINPUT,d0
bsr DoPacket
beq.s .fail2
movem.l a2/a3,-(sp)
move.l fib_Size(a3),d2
move.l myf_Parent(a2),a3
lea myf_Name(a2),a2
bsr CreateNewObject
movem.l (sp)+,a2/a3
beq.s .fail3
move.l d0,d2
add.l d1,d2
move.l a2,a1
move.l d0,a2
bsr DeleteObj
beq.s .fail3
move.l fh_Arg1(a4),a4
move.l a4,d1
move.l fib_Size(a3),d3
moveq #ACTION_READ,d0
bsr DoPacket
bsr UpdateNotify
.fail3 move.l a4,d1
move.l #ACTION_END,d0
bsr DoPacket
move.l a2,d4
.fail2 move.l a3,a1
move.l #fib_SIZEOF+fh_SIZEOF,d0
bsr FreeMem
.fail move.l d4,d0
movem.l (sp)+,d2-d5/a2-a4
rts
*******************************************************
IFD DEBUG
RawHook move.l a6,-(sp)
move.l 4.w,a6
jsr _LVORawPutChar(a6)
move.l (sp)+,a6
rts
wait_c:
movem.l d0-d1/a0-a1,-(sp)
moveq #0,d0
moveq #0,d1
bset #12,d1
jsr _LVOSetSignal(a6)
moveq #0,d0
bset #12,d0
jsr _LVOWait(a6) wait for CTRL-C
movem.l (sp)+,d0-d1/a0-a1
rts
IFD VERBOSE
txstart dc.b "Handler started, A5=$%lx.",10,0
txend dc.b "Handler ended, FileSize=%ld, TotalSize=%ld.",10,0
txcopy dc.b "Copyfrom: Port=$%lx, Lock=$%lx.",10,0
txpack dc.b "Type=%ld Arg1=$%lx Arg2=$%lx Arg3=$%lx.",10,0
txres dc.b "Result1=$%lx, Result2=%ld.",10,0
txpkt dc.b " Packet=$%lx, type=%ld, res=$%lx, err=%ld.",10,0
txerr1 dc.b " %ld: Unknown Action.",10,0
txopeno dc.b " Oldopen lock=$%lx.",10,0
txopenn dc.b " Newopen lock=$%lx.",10,0
txcreat dc.b " Created file %s=$%lx size=%ld.",10,0
txread dc.b " Read %ld of %ld bytes, pos=%ld.",10,0
txwrite dc.b " Wrote %ld bytes, pos=%ld, size=%ld.",10,0
txwins dc.b " Inserted %ld bytes at %ld.",10,0
txseek dc.b " Seeked, filepos=%ld.",10,0
txdel dc.b " Deleted $%lx.",10,0
txlock dc.b " Locked %s=$%lx mode %ld.",10,0
txulock dc.b " Unlocked $%lx.",10,0
txexam dc.b " Examined file=$%lx.",10,0
txexnx dc.b " Examined next file=$%lx.",10,0
txfnd dc.b " Found %s=$%lx.",10,0
txentry dc.b " Found entry %s.",10,0
txsplit dc.b " Splitted ->%s,%s.",10,0
txfull dc.b " Full name: %s.",10,0
txanoti dc.b " Added noti $%lx->$%lx on %s key=$%lx.",10,0
txrnoti dc.b " Removed noti $%lx->$%lx.",10,0
txcnoti dc.b " Checking noti on %s.",10,0
txunoti dc.b " Updated noti on %s key=$%lx.",10,0
txsnoti dc.b " Sent signal to %s for %s.",10,0
txmnoti dc.b " Sent message $%lx to %s for %s.",10,0
txgnoti dc.b " Got message $%lx.",10,0
ENDC
IFND VERBOSE
txstart dc.b "Handler started, A5=$%lx.",10,0
txend dc.b "Handler ended, FileSize=%ld, TotalSize=%ld.",10,0
txcopy dc.b "Copyfrom: Port=$%lx, Lock=$%lx.",10,0
txpack dc.b 0;"Type=%ld Arg1=$%lx Arg2=$%lx Arg3=$%lx.",10,0
txres dc.b 0;"Result1=$%lx, Result2=%ld.",10,0
txpkt dc.b 0;" Packet=$%lx, type=%ld, res=$%lx, err=%ld.",10,0
txerr1 dc.b " %ld: Unknown Action.",10,0
txopeno dc.b 0;" Oldopen lock=$%lx.",10,0
txopenn dc.b 0;" Newopen lock=$%lx.",10,0
txcreat dc.b " Created file %s=$%lx size=%ld.",10,0
txread dc.b 0;" Read %ld of %ld bytes, pos=%ld.",10,0
txwrite dc.b 0;" Wrote %ld bytes, pos=%ld, size=%ld.",10,0
txwins dc.b 0;" Inserted %ld bytes at %ld.",10,0
txseek dc.b 0;" Seeked, filepos=%ld.",10,0
txdel dc.b " Deleted $%lx.",10,0
txlock dc.b 0;" Locked %s=$%lx mode %ld.",10,0
txulock dc.b 0;" Unlocked $%lx.",10,0
txexam dc.b 0;" Examined file=$%lx.",10,0
txexnx dc.b 0;" Examined next file=$%lx.",10,0
txfnd dc.b 0;" Found %s=$%lx.",10,0
txentry dc.b 0;" Found entry %s.",10,0
txsplit dc.b 0;" Splitted ->%s,%s.",10,0
txfull dc.b 0;" Full name: %s.",10,0
txanoti dc.b 0;" Added noti $%lx->$%lx on %s key=$%lx.",10,0
txrnoti dc.b 0;" Removed noti $%lx->$%lx.",10,0
txcnoti dc.b 0;" Checking noti on %s.",10,0
txunoti dc.b 0;" Updated noti on %s key=$%lx.",10,0
txsnoti dc.b 0;" Sent signal to %s for %s.",10,0
txmnoti dc.b 0;" Sent message $%lx to %s for %s.",10,0
txgnoti dc.b 0;" Got message $%lx.",10,0
ENDC
ENDC